#pragma once
#include <iostream>
#include <string>
#include <vector>
#include "InetAddr.hpp"
#include "Log.hpp"
#include "Mutex.hpp"

using namespace LogModule;
using namespace MutexModule;

class Route
{
public:
	Route() {}
	~Route() {}

	bool IsExist(const InetAddr &addr)
	{
		for (auto &iter : _online_user)
		{
			if (iter == addr)
				return true;
		}

		return false;
	}

	void AddUser(InetAddr &addr)
	{
		if (!IsExist(addr))
		{
			_online_user.emplace_back(addr);
			LOG(LogLevel::INFO) << "添加了一个新用户 [" << addr.Ip() << ":" << addr.Port() << "]";
		}
	}

	void DeleteUser(InetAddr &addr)
	{
		for (auto iter = _online_user.begin(); iter != _online_user.end(); iter++)
		{
			if (*iter == addr)
			{
				_online_user.erase(iter);
				LOG(LogLevel::INFO) << "删除了一个用户 [" << addr.Ip() << ":" << addr.Port() << "]";
				return;
			}
		}
	}

	void MessageRoute(int sockfd, const std::string &message, InetAddr &peer)
	{
		MutexGuard guard(_mutex); // 加锁
		// 首个用户上线无需广播
		if (!IsExist(peer))
		{
			AddUser(peer);
		}

		std::string send_message = peer.StringAddr() + "#" + message;
		LOG(LogLevel::INFO) << "正在广播消息: " << send_message;
		
		for (auto iter = _online_user.begin(); iter != _online_user.end(); iter++)
		{
			struct sockaddr_in user_addr = iter->GetAddr(); // 保存副本到局部变量
			sendto(sockfd, send_message.c_str(), send_message.size(), 0, (const struct sockaddr *)&user_addr, sizeof(user_addr)); // 取局部变量地址
		}

		if (message == "QUIT")
		{
			DeleteUser(peer);
		}
	}

private:
	std::vector<InetAddr> _online_user;
	Mutex _mutex;
};